//
// Unihan Input Method
//
// Copyright © 2002-2007 Sun Wah Linux Ltd.
//
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
// USA
//
// $Id: aux.c 757 2007-05-10 08:19:31Z roger $
//

/* FILE : aux.c */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <stdio.h>
#include <string.h>

#include <unihan_im.h>
#include <SWTable.h>

#include "im_config.h"
#include "candidates.h"
#include "context.h"
#include "table.h"

void
preedit_draw(UnihanIM *uim)
{
#if DEBUG
	fprintf(stderr, "table : preedit draw\n");
#endif
	TableDesktopList *desktop = (TableDesktopList *)uim->desktopUserData;
	TableSession *session = (TableSession *)uim->sessionUserData;
	Context *context = session->context;
	Node *sentence = context->sentence;
	Node *node = sentence;
	const char *c = NULL;
        char *peString = NULL, *p = NULL;
        int len = 0;
	int cursor = 0;
	int i = 0;

        // see how long the PE string would be in UTF-8
	while (node) {
		if (node->kicked) {
			len += node->defaultCandLen;
		} else {
			c = node_get_preedit(node);
			while (*c) {
				len += strlen(desktop->baseTable->keyName[idx(*c)].name);
				++c;
			}
		}
		node = node->next;
	}
        uim->m->mem_alloc(uim, len + 1, (void**)&peString);
        memset(peString, 0, len + 1);

        p = peString;

	node = sentence;
	while (node) {
		if (node->kicked) {
			len = node->defaultCandLen;
			strcpy(p, node_get_selected_candidates(node,
						desktop->baseTable,
						desktop->phraseTableList));
			p += len;
		} else {
			c = node_get_preedit(node);
			while (*c) {
				char *keyName = desktop->baseTable->keyName[idx(*c)].name;
				len = strlen(keyName);
				memcpy(p, keyName, len);
				p += len;
				++c;
			}
		}
		i++;
		if (i <= session->context->cursor) {
			if (!node->kicked)
				cursor += node_preedit_len(node);
			else
				cursor++;
		}
		node = node->next;
	}
	uim->m->preedit_draw(uim, peString, NULL);
#if 0
	fprintf(stderr, "table : caret pos %d\n", cursor);
#endif
        uim->m->preedit_caret_pos(uim, cursor);
}

void
preedit_erase(UnihanIM *uim)
{
#if DEBUG
	fprintf(stderr, "table : preedit erase\n");
#endif
	uim->m->preedit_erase(uim);
	return;
}

void
lookup_draw(UnihanIM *uim)
{
#if DEBUG
	fprintf(stderr, "table : lookup draw\n");
#endif
	TableDesktopList *desktop = (TableDesktopList *)uim->desktopUserData;
	TableSession *session = (TableSession *)uim->sessionUserData;
	//TableConfig *config = session->config;
	Context *context = session->context;
	Node *node = context->currNode;
	UnihanLookupDraw ludraw;
	int numCands = 0;
	int i,j;

	if (session->lookupShown == 0) {
		UnihanLookupStart lustart;
		lustart.choicePerWindow = 9;
		lustart.numColumns = 9;
		lustart.numRows = 1;
		lustart.direction = UNIHAN_LOOKUP_DIRECTION_RIGHT;
		uim->m->lookup_start(uim, &lustart);
		session->lookupShown = 1;
	}

	if ((node->page+1)*9 >= node->numTotalCands) {
		ludraw.numChoices = node->numTotalCands - node->page*9;
	} else
		ludraw.numChoices = (node->numTotalCands > 9)?9:node->numTotalCands;

	ludraw.selected = node->luCurrCandOffset;
        ludraw.currentChoice = node->luCurrCandOffset;
        ludraw.totalChoices = ludraw.numChoices;
	ludraw.title = "";
	uim->m->mem_alloc(uim, sizeof(char *)*ludraw.numChoices,
			(void**)&ludraw.label);
	uim->m->mem_alloc(uim, sizeof(char *)*ludraw.numChoices,
			(void**)&ludraw.value);

	for (i=0, j=0; i < ludraw.numChoices; i++, j++) {
		int index;
		UnihanTCSCMode tcsc;
		char *cand;
		char *key;
		char *pehint = NULL;
		char *converted = NULL;
		int len = 0;

		uim->m->mem_alloc(uim, sizeof(char)*2,
				(void**)&(ludraw.label[i]));
		ludraw.label[i][0] = i + '1';
		ludraw.label[i][1] = 0;

		/* gcc always warn me , so I dup candidate string and key*/
                cand = strdup(node_get_candidates(node,
					node->page * 9 + i,
					desktop->baseTable,
					desktop->phraseTableList));

                key = strdup(node_get_preedit(node));

                len = strlen(cand);

                if (node_preedit_len(node) < strlen(key)) {
                        pehint = key + node_preedit_len(node);
                        len += strlen(pehint) + 1;
                }

                uim->m->tcsc_mode_get(uim, &tcsc);
                if (tcsc != UNIHAN_TCSC_NO_CONV) {
                        uim->m->tcsc_do_conv(uim, tcsc, cand, &converted);

                        if (!strcmp(converted, cand)) {
                                converted = NULL;
                        } else {
                                len += strlen(converted) + 5; // for the arrow
                        }
                }

                uim->m->mem_alloc(uim, len + 1, (void**)&(ludraw.value[i]));
                memset(ludraw.value[i], 0, len + 1);
                if (pehint) {
                        strcat(ludraw.value[i], pehint);
                        strcat(ludraw.value[i], " ");
                }
                strcat(ludraw.value[i], cand);
                if (converted) {
                        strcat(ludraw.value[i], " \342\206\222 "); // U+2192 right arrow
                        strcat(ludraw.value[i], converted);
                }
		free(cand);
		cand = NULL;
		free(key);
	}
	ludraw.labelStyles = NULL;
	ludraw.valueStyles = NULL;

	uim->m->lookup_draw(uim, &ludraw);
	return;
}

void
lookup_done(UnihanIM *uim)
{
#if DEBUG
	fprintf(stderr, "table : lookup done\n");
#endif
	TableSession *session = (TableSession *)uim->sessionUserData;

	if (session->lookupShown != 0) {
		uim->m->lookup_done(uim);
		session->lookupShown = 0;
	}
}

void
aux_draw(UnihanIM *uim)
{
	return;
}

void
aux_done(UnihanIM *uim)
{
	return;
}

void
commit(UnihanIM *uim)
{
#if DEBUG
	fprintf(stderr, "table : commit result\n");
#endif
	TableDesktopList *desktop = (TableDesktopList *)uim->desktopUserData;
	TableSession *session = (TableSession *)uim->sessionUserData;
	Context *context = session->context;
	Node *node = context->sentence;
        UnihanTCSCMode tcsc;

        uim->m->tcsc_mode_get(uim, &tcsc);
	while (node) {
		if (tcsc == UNIHAN_TCSC_NO_CONV) {
			uim->m->commit_string(uim,
					(char *)node_get_selected_candidates(node,
						desktop->baseTable,
						desktop->phraseTableList)
					);
		} else {
			char *cnvd = NULL;
			uim->m->tcsc_do_conv(uim,
				tcsc,
				(char *)node_get_selected_candidates(node,
					desktop->baseTable,
					desktop->phraseTableList),
				&cnvd);
			uim->m->commit_string(uim, cnvd);
			free(cnvd);
		}
		if (!node->punc) {
			node_post_freq(node,
					desktop->baseTable,
					desktop->adjuster,
					session->config);
		}
		node = node->next;
	}
}

void
commit_string(UnihanIM *uim, const char *string)
{
#if DEBUG
	fprintf(stderr, "table : commit string\n");
#endif
	TableDesktopList *desktop = (TableDesktopList *)uim->desktopUserData;
	TableSession *session = (TableSession *)uim->sessionUserData;
        UnihanTCSCMode tcsc;

        uim->m->tcsc_mode_get(uim, &tcsc);
	if (tcsc == UNIHAN_TCSC_NO_CONV) {
		uim->m->commit_string(uim, (char *)string);
	} else {
		char *cnvd = NULL;
		uim->m->tcsc_do_conv(uim,
			tcsc,
			(char *)string,
			&cnvd);
		uim->m->commit_string(uim, cnvd);
		free(cnvd);
	}
}

void
beep(UnihanIM *uim)
{
#if DEBUG
	fprintf(stderr, "table : beep\n");
#endif
	uim->m->beep(uim);
}

// vi:ts=4:nowrap:cin:expandtab
